package sql2xml;
import java.io.FileWriter;
import java.sql.*;
import java.text.SimpleDateFormat;



import org.jdom2.*;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

import java.text.ParseException;

//Кодировка файла - UTF
public  class form30_sql2xml {

	static String user = "postgres"; 
	static String password = "1_P0$tgre$!";
	static String server = "jdbc:postgresql://192.168.0.3:5432/riams";
	static Element rootElement = new Element("children");
	
	/*
	 * Забираем данные  из postgreSQL и выводим их в xml для импорта на сайте минздрава (ДД подростков).
	 */
			
	public static void main (String[] args) throws ParseException
		{


		Document pat = new Document (rootElement);
		
		String SQLreq;  //Извлечение направлений на определенную дату
		
		
		SQLreq ="select edc.id as did, p.id as pid,p.lastname, p.firstname, p.middlename, p.sex_id as sex, p.snils "
				+ ", to_char(p.birthday,'dd.mm.yyyy') as birthday "
				+ ",to_char(edc.startDate,'dd.mm.yyyy') as edcBeginDate "
				+ ",to_char(edc.finishDate,'dd.mm.yyyy') as edcFinishDate "
				+ ",edc.dispType_id "
				+ ",mkb.code as mkbcode ,vedag.name as vedagname ,vedsg.name as vedsgname ,vedhg.code as vedhgcode "
				+ ",mp.company_id "
				+ ",edc.isObservation as cntDispM "
				+ ",edc.isTreatment as cntLechM "
				+ ",edc.isDiagnostics as cntDiagM "
				+ ",p.commonnumber as RZ "
				+ ",p.passportseries as passSer "
				+ ",p.passportnumber passNum "
				+ ",p.passporttype_id as passID "
				+ ",pwr.lastname as vrach_l " 
				+ ",pwr.firstname as vrach_f "
				+ ",pwr.middlename as vrach_m "
				//+ ",COALESCE(adr.fullname,'') || ' Д.' || COALESCE(p.housenumber,'') || ' Корп.' || COALESCE(p.housebuilding,'') || ' Кв.' || COALESCE(p.flatnumber,'') AS adres "
				+ ",edc.isServiceIndication as cntIsServiceIndication "
				+ "from ExtDispCard edc "
				+ "left join WorkFunction wf on wf.id=edc.workFunction_id "
				+ "left join Worker w on w.id=wf.worker_id "
				+ "left join Patient pwr on pwr.id=w.person_id "
				+"left join MisLpu lpu on lpu.id=w.lpu_id "
				+"left join Patient p on p.id=edc.patient_id "
				+"left join VocExtDisp ved on ved.id=edc.dispType_id "
				+"left join VocExtDispHealthGroup vedhg on vedhg.id=edc.healthGroup_id "
				+"left join VocExtDispSocialGroup vedsg on vedsg.id=edc.socialGroup_id "
				+"left join VocExtDispAgeGroup vedag on vedag.id=edc.ageGroup_id "
				+"left join ExtDispRisk edr on edr.card_id=edc.id "
				+"left join VocExtDispRisk vedr on vedr.id=edr.dispRisk_id "
				+"left join VocIdc10 mkb on mkb.id=edc.idcMain_id "
				+"left join ExtDispService eds on eds.card_id=edc.id and eds.serviceDate is not null "
				+"left join (select company_id,patient_id from medpolicy limit 1) mp on mp.patient_id = p.id "
				+"where edc.finishDate between to_date('01.09.2014','dd.mm.yyyy') " 
				+"and to_date('16.09.2014','dd.mm.yyyy') " 
				+"and edc.dispType_id in ('3','4','5','9','10','11','12') " 
				+"group by edc.id,p.lastname,p.firstname, p.middlename "
				+ ",p.birthday "
				+ ",edc.startDate "
				+ ",edc.finishDate "
				+ ",edc.dispType_id "
				+ ",vedag.name,vedhg.code,vedsg.name "
				+ ",edc.isObservation ,edc.isTreatment "
				+ ",edc.isDiagnostics ,edc.isSpecializedCare "
				+ ",edc.isSanatorium ,mkb.code "
				+ ",edc.isServiceIndication "
				+ ",p.commonnumber ,p.passportseries ,p.passportnumber "
				+ ", p.sex_id, p.snils "
				+ ",p.passporttype_id ,mp.company_id "
				+ ",p.id "
				+ ",pwr.lastname " 
				+ ",pwr.firstname "
				+ ",pwr.middlename "
				+"order by p.lastname,p.firstname,p.middlename";
				
		
			System.out.println("Поиск записей:");
			find_data(SQLreq, rootElement);
			
			
			
			
			try 
			{
				
				XMLOutputter outputter = new XMLOutputter();
				FileWriter fwrt = new FileWriter("output.xml");
				
				outputter.setFormat(Format.getPrettyFormat().setEncoding("UTF-8"));
				outputter.output(pat, fwrt);
				fwrt.close();
			}
		
			 catch (Exception ex) 
			{
				 System.out.println(ex.getMessage());
		        }
			
			}
	
	public static void find_data(String arg0, Element arg1)  throws ParseException
		{
		String error_text="";	
		String SQLReq = arg0;
			
			Statement statement = null;
			Element rootElement = arg1; 
			
			/*
			Выбрать все исследования, где card_number - card_num
			*/
			
			
			try 
			{
				Class.forName("org.postgresql.Driver");
			}
			
			catch (ClassNotFoundException e) 
			{
			    System.out.println("PosgreSQL driver not found");
			    e.printStackTrace();
			    return;
			}
			try
			{
				
				Connection dbh = DriverManager.getConnection(server, user, password);
				statement = dbh.createStatement();
				ResultSet rs = statement.executeQuery(SQLReq);
				int numAll = 0;
				
				// Значения по умолчания для всех записей.
				String sex = "1";
				String p_idType="3"; //3 - несовершеннолетний. Если сирота - то "1"
				String p_idCategory = "4"; //Категория ребенка. 4 - без категории. 1 - сирота, 2 - ТЖС, 3 - опекаемый
				int card_idType; //1 - DD sirot, 2-prof, 3-predvar, 4 - period
				
				String card_height = "150"; //rost in SM
				String card_weight = "20"; //ves in SM
				String card_headSize = "30";  //okrujn. golova
				String card_reccomend = "";
				String card_recommendZOZH = "Не пить, не курить";
				String health_G = "2"; //Группа здоровья для физкультуры
				int fileLet = 60;
				int tenLet = 120;
				
			while (rs.next()) 
				{
				numAll+=1;
				
				if (rs.getString("sex").equals("1")) sex = "2"; else sex="1";
				String card_id = rs.getString("did");
				
				switch (Integer.parseInt(rs.getString("dispType_id"))) { //Определяем тип ДД
	            case 3:  card_idType = 3;
	                     break;
	            case 4:  card_idType = 3;
	                     break;
	            case 5:  card_idType = 3;
	                     break;
	            case 9:  card_idType = 2;
	                     break;
	            case 10:  card_idType = 4;
	                     break;
	            case 11:  card_idType = 4;
	            	break;
	            case 12:  card_idType = 4;
	                     break;
	            default: card_idType = 0;
	            error_text+=" !Ошибка - код_ДД-" + rs.getString("dispType_id");
	                     break;
				}
				String s_card_idType = Integer.toString(card_idType);
				Element card_basic = new Element("basic");
				Element card_issled = new Element("issled");
				Element card_osmotri = new Element("osmotri");
				
				String vrach_f=rs.getString("vrach_f"); //ФИО врача
				String vrach_l=rs.getString("vrach_l");
				String vrach_m=rs.getString("vrach_m");
				String pid = rs.getString("pid");
				String card_issl_result = "Без патологий"; // Результат анализов
				int monthLet = getDaysDiff(toDate(rs.getString("edcBeginDate")),toDate(rs.getString("birthday")));
				String smonthLet = Integer.toString(monthLet);
				String InsuranceCompany = getOMCNumber(pid,dbh);
				statement = dbh.createStatement();
				
				
				//Ищем все исследования
				{
				String SQLissled = "SELECT servicedate as date "
						+ ", servicetype_id as iss_id "
						+ "FROM extdispservice "
						+ "where card_id = " + card_id + " and dtype='ExtDispExam'";
       								
				ResultSet rs_issled = statement.executeQuery(SQLissled);
					while (rs_issled.next())
					{
						int iss_id = Integer.parseInt(rs_issled.getString("iss_id"));
						switch (iss_id) {
			            case 133:  iss_id = 1;
			                     break;
			            case 134:  iss_id = 2;
			                     break;
			            case 137:  iss_id = 3;
			                     break;
			            case 136:  iss_id = 4;
			                     break;
			            case 139:  iss_id = 5;
			                     break;
			            case 127:  iss_id = 6;
			            	break;
			            case 128:  iss_id = 7;
			                     break;
			            case 129:  iss_id = 8;
	                     break;
			            case 130:  iss_id = 9;
	                     break;
			            case 131:  iss_id = 10;
	                     break;
			            case 132:  iss_id = 11;
	                     break;
			            case 138:  iss_id = 12;
	                     break;
			            case 135:  iss_id = 13;
	                     break;
			            case 140:  iss_id = 14;
	                     break;
			            case 126:  iss_id = 15;
	                     break;
			            case 145:  iss_id = 17;
	                     break;
			            default: iss_id = 0;
			            error_text+=" !Ошибка - код исследования-" + rs_issled.getString("iss_id");
			                     break;
						}
					card_basic.addContent(new Element("record")
						.addContent(new Element("id").addContent(Integer.toString(iss_id)))
							.addContent(new Element("date").addContent(rs_issled.getString("date")))
							.addContent(new Element("result").addContent(card_issl_result))
						);
					}
				} //Заканчивается поиск услуг
				
					card_issled.addContent(card_basic);
					
					{  //Запускаем поиск осмотров специалистами
					
					String SQLosmotri = "SELECT servicedate as date "
							+ ", servicetype_id as iss_id "
							+ "FROM extdispservice "
							+ "where card_id = " + card_id + " and dtype='ExtDispVisit'";
	       			
					
					ResultSet rs_osmotri = statement.executeQuery(SQLosmotri);
						while (rs_osmotri.next())
						{
							int iss_id = Integer.parseInt(rs_osmotri.getString("iss_id"));
							switch (iss_id) {
				            case 113:  iss_id = 1;
				            		break;
				            case 114:  iss_id = 2;
		                     		break;
				            case 116:  iss_id = 3;
				                     break;
				            case 115:  iss_id = 4;
				                     break;
				            case 119:  iss_id = 5;
				                     break;
				            case 117:  iss_id = 6;
				                     break;
				            case 120:  iss_id = 7;
		                     break;
				            case 118:  iss_id = 8;
		                     break;
				            case 123:  iss_id = 9;
		                     break;
				            case 122:  iss_id = 10;
		                     break;
				            case 121:  iss_id = 11;
		                     break;
				            case 124: iss_id = 7;
				            	break;
				            default: iss_id = 0;
				            error_text+=" !Ошибка - код осмотра-" + rs_osmotri.getString("iss_id");
				                     break;
							}
						card_osmotri.addContent(new Element("record")
							.addContent(new Element("id").addContent(Integer.toString(iss_id)))
								.addContent(new Element("date").addContent(rs_osmotri.getString("date")))
							);
						}
					} //Заканчивается поиск осмотров специалистами
				
					
				/*
				 fio, sex, snils, birthday, edcBeginDate, edcFinishDate, RZ, passSer, passNum, passID, adres
				*/
				
				Element currPat = new Element ("child")
				.addContent(new Element("idInternal").addContent(rs.getString("pid")))
				.addContent(new Element("idType").addContent(p_idType)) 
				.addContent(new Element("name")
					.addContent(new Element("last").addContent(rs.getString("lastname")))
					.addContent(new Element("first").addContent(rs.getString("firstname")))
					.addContent(new Element("middle").addContent(rs.getString("middlename"))))
				.addContent(new Element("idSex").addContent(sex))
				.addContent(new Element("dateOfBirth").addContent(toDate(rs.getString("birthday"))))
				.addContent(new Element("idCategory").addContent(p_idCategory))
				.addContent(new Element("idDocument").addContent(rs.getString("passID")))
				.addContent(new Element("documentSer").addContent(rs.getString("passSer")))
				.addContent(new Element("documentNum").addContent(rs.getString("passNum")))
				//.addContent(new Element("snils").addContent("000-000-000-00"))//rs.getString("snils")))
				//.addContent(new Element("polisSer").addContent(""))
				.addContent(new Element("polisNum").addContent(rs.getString("RZ")))
				.addContent(new Element("idInsuranceCompany").addContent(InsuranceCompany))
				.addContent(new Element("medSanName").addContent("ГБУЗ \"Детская городская поликлиника №5\", г. Астрахань"))
				.addContent(new Element("medSanAddress").addContent("г. Астрахань, пр. Воробьёва, 11/11"))
				.addContent(new Element("address")
				//	.addContent(new Element("index").addContent("414000"))
					.addContent(new Element("kladrNP").addContent("30000001000000")) //Код нас. пункта по KLADR
				//	.addContent(new Element("kladrStreet").addContent("00000000000000000")) //Код улицы по KLADR
				//	.addContent(new Element("house").addContent("1")) //номер дома
				//	.addContent(new Element("building").addContent("1")) //Корпус
				//	.addContent(new Element("appartment").addContent("1")) //Квартира
				);
			//	.addContent(new Element("idEducationOrg").addContent(""))
			//	.addContent(new Element("idOrphHabitation").addContent("")) //Место текущего нахождения
			//	.addContent(new Element("dateOrphHabitation")) //Дата поступление в место текущего нахождения - для сироты - расскоментить
			//	.addContent(new Element("idStacOrg").addContent(""));	//Справочный идентификатор стационарного учреждения	
				Element cards = new Element("cards");
				
				Element card = new Element("card")
							.addContent(new Element("idInternal").addContent(card_id))
							.addContent(new Element("dateOfObsled").addContent(toDate(rs.getString("edcBeginDate")))) //Дата начала обследования
						//	.addContent(new Element("ageObsled").addContent("")) //Возраст ребёнка в месяцах на момент проведения обследования (необязательно)
							.addContent(new Element("idType").addContent(s_card_idType)) 
							.addContent(new Element("height").addContent(card_height))
							.addContent(new Element("weight").addContent(card_weight))
							.addContent(new Element("headSize").addContent(card_headSize));
//							.addContent(new Element("healthProblems")
//								.addContent(new Element("problem").addContent(""))
//								);
//							
				//System.out.println(monthLet);	
				if (monthLet<fileLet)
						{
							card.addContent(new Element("pshycDevelopment") //Оценка возраста психического развития для детей от 0 до 4 лет в месяцах (по умолчанию - кол-во месяцев)
									.addContent(new Element("poznav").addContent(smonthLet)) // познавательная функция
									.addContent(new Element("motor").addContent(smonthLet)) //моторная функция
									.addContent(new Element("emot").addContent(smonthLet))	//эмоциональная и социальная (контакт с окружающим миром) функции		
									.addContent(new Element("rech").addContent(smonthLet)) //предречевое и речевое развитие
								);
						}
					else
						{
							card.addContent(new Element("pshycState") //Оценка состояния психического развития для детей от 5 лет (0 - в норме)
									.addContent(new Element("psihmot").addContent("0")) //Психомоторная сфера
									.addContent(new Element("intel").addContent("0")) // Интеллект
									.addContent(new Element("emotveg").addContent("0")) //Эмоционально-вегетативная сфера
								);
						}
					if (monthLet>tenLet)
						{
							if (sex.equals("1"))
							{
							card.addContent(new Element("sexFormulaMale")  //Половая формула (муж.) старше 10 лет
								.addContent(new Element("P").addContent("1"))
								.addContent(new Element("Ax").addContent("1"))
								.addContent(new Element("Fa").addContent("1"))
							);
							}
							else 
							{
							card.addContent(new Element("sexFormulaFemale") // Половая формула (жен.)
								.addContent(new Element("P").addContent("1"))
								.addContent(new Element("Ma").addContent("1"))
								.addContent(new Element("Ax").addContent("1"))
								.addContent(new Element("Me").addContent("1"))
							);
							card.addContent(new Element("menses") //  Менструальная функция
								.addContent(new Element("menarhe").addContent("144"))
								.addContent(new Element("characters")
									.addContent(new Element("char").addContent("1"))
								)
							);
							}
						}
								card.addContent(new Element("healthGroupBefore").addContent(rs.getString("vedhgcode"))) //Группа здоровья до проведения обследования (числом)
								.addContent(new Element("fizkultGroupBefore").addContent(health_G)) // Медицинская группа для занятий физической культурой
								.addContent(new Element("diagnosisBefore")
									.addContent(new Element("diagnosis")
										.addContent(new Element("mkb").addContent(rs.getString("mkbcode")))
										.addContent(new Element("dispNablud").addContent("3")) //Диспансерное наблюдение (1,0 - уст, 3 - не уста)
										.addContent(new Element("lechen") //Лечение назначено
											.addContent(new Element("condition").addContent("1")) //условия (1,2,3)1 - амбулаторно
											.addContent(new Element("organ").addContent("2")) //организация (2 - ГБУЗ)
										//	.addContent(new Element("notDone").addContent("") //Причина невыполнения
										//		.addContent(new Element("reason").addContent(""))
										//		.addContent(new Element("reasonOther").addContent(""))
										//	)
										)
//										.addContent(new Element("reabil").addContent("") //Лечение назначено
//											.addContent(new Element("condition").addContent("1")) //условия стационар?(1,2,3)
//											.addContent(new Element("organ").addContent("2")) //организация (2 - ГБУЗ)
//											.addContent(new Element("notDone").addContent("") //Причина невыполнения
//												.addContent(new Element("reason").addContent(""))
//												.addContent(new Element("reasonOther").addContent(""))
//											)
//										)
										.addContent(new Element("vmp").addContent("0")) //ВМП рекоменд. и оказана (1), рек+не ок(2), не рек(0)
									));
								//System.out.println(rs.getString("vedhgcode"));
									if (rs.getString("vedhgcode").equals("1"))
									{
										card.addContent(new Element("healthyMKB").addContent(rs.getString("mkbcode"))); //Код осмотра, если ребёнок здоров (Z00-Z99)
									}
									else
									{
									card.addContent(new Element("diagnosisAfter").addContent("")
											.addContent(new Element("diagnosis").addContent("")
												.addContent(new Element("mkb").addContent(rs.getString("mkbcode")))
												.addContent(new Element("firstTime").addContent("0")) //выявлен впервые? 1,0
												.addContent(new Element("dispNablud").addContent("0")) //Диспансерное наблюдение уст_впервые2, уст. ранее1, не уст.0
												.addContent(new Element("lechen")
													.addContent(new Element("condition").addContent("1")) //условия стационар?(1-амб,2,3)
													.addContent(new Element("organ").addContent("2")) //организация (2 - ГБУЗ)
												)
//												.addContent(new Element("reabil")
//													.addContent(new Element("condition").addContent("")) //условия стационар?(1,2,3)
//													.addContent(new Element("organ").addContent("")) //организация (2 - ГБУЗ)
//												)
//												.addContent(new Element("consul") //Дополнительные консультации и исследования назначены
//													.addContent(new Element("condition").addContent("")) //условия стационар?(1,2,3)
//													.addContent(new Element("organ").addContent("")) //организация (2 - ГБУЗ)
//													.addContent(new Element("state").addContent("")) //Консультации выполнены или не выполнены (0,1,2).
//												)
												.addContent(new Element("needVMP").addContent("0")) //Рекомендована ВМП (0-1)
												.addContent(new Element("needSMP").addContent("0")) //Рекомендована СМП (0-1)
												.addContent(new Element("needSKL").addContent("0")) //Рекомендовано СКЛ (0-1)
												.addContent(new Element("recommendNext").addContent(card_reccomend)) //Рекомендации по диспансерному наблюдению, лечению, 
											)
									);
									}
//									.addContent(new Element("invalid").addContent("")
//											.addContent(new Element("type").addContent("")) //  Вид инвалидности ( с рождения/нет 1-2)
//											.addContent(new Element("dateFirstDetected").addContent("")) //Дата первого освидетельствования
//											.addContent(new Element("dateLastConfirmed").addContent("")) //Дата последнего освидетельствования
//											.addContent(new Element("illnesses").addContent("") // Заболевания, обусловившие возникновение инвалидности
//													.addContent(new Element("illness").addContent(""))
//											)
//											.addContent(new Element("defects").addContent("") // Виды нарушений в состоянии здоровья 1-9
//													.addContent(new Element("defect").addContent(""))
//											)
//									);
							
									card.addContent(card_issled);
									card.addContent(new Element("healthGroup").addContent(rs.getString("vedhgcode")));
									card.addContent(new Element("fizkultGroup").addContent(health_G)); // группа занятия физкультурой
									card.addContent(new Element("zakluchDate").addContent(toDate(rs.getString("edcFinishDate"))));
									card.addContent(new Element("zakluchVrachName")
											.addContent(new Element("last").addContent(vrach_l))
											.addContent(new Element("first").addContent(vrach_f))
											.addContent(new Element("middle").addContent(vrach_m))
									);
									card.addContent(card_osmotri);
									cards.addContent(card);
									currPat.addContent(cards);
									card.addContent(new Element("recommendZOZH").addContent(card_recommendZOZH));
//									card.addContent(new Element("reabilitation")
//											.addContent(new Element("date"))
//											.addContent(new Element("state"))
//									);
									card.addContent(new Element("privivki")
											.addContent(new Element("state").addContent("1")) // Привит по возрасту
//											.addContent(new Element("privs")
//													.addContent(new Element("priv")))
								);
									card.addContent(new Element("oms").addContent("0"));

									rootElement.addContent(currPat);
				}
			
			dbh.close();
			System.out.println("Всего записей = " + numAll);
			System.out.println();
			System.out.println(error_text);
			}
			
		catch (SQLException e)
			{
	        System.out.println(e.getMessage());
			}	
		}
	public static String getOMCNumber(String arg, Connection dbh2)
	{
		String ret = "0";
		String SQLReq = "SELECT company_id  FROM medpolicy where patient_id = "+ arg + " order by actualdatefrom desc limit 1";
		try{
			
			Connection dbh = DriverManager.getConnection(server, user, password);
			Statement statement = dbh.createStatement();
			ResultSet rs = statement.executeQuery(SQLReq);
			while (rs.next())
			{
				if (rs.getString("company_id").equals("2")) ret = "115";
				else if (rs.getString("company_id").equals("1")) ret = "103"; 
				dbh.close();
			}
		}
		
		catch (SQLException e)
		{
        System.out.println(e.getMessage());
		}
		return ret;
	}
	
	public static String toDate(String args)throws ParseException
	{
		SimpleDateFormat nDate = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat nDate2 = new SimpleDateFormat("dd.MM.yyyy");
		
		return nDate.format(nDate2.parse(args)).toString();
	}
	
	public static int getDaysDiff(String args1, String args2)throws ParseException
	{
		SimpleDateFormat nDate = new SimpleDateFormat("yyyy-MM-dd");
		//SimpleDateFormat nDate2 = new SimpleDateFormat("dd.MM.yyyy");
		java.util.Date date1 = nDate.parse(args1);//.compareTo(nDate.parse(args2)); 
		java.util.Date date2 = nDate.parse(args2);
		 double difference = (date1.getTime() - date2.getTime())/1000/60/60/24/30.5; 
		 int i = (int) Math.round(difference);
		 return i;
		//return nDate.parse(args1).compareTo(nDate.parse(args2));
	}
		

}